梦入琼楼寒有月,行过石树冻无烟

Vue 组件基础

创建组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="button-counts">
<button-conters></button-conters>
</div>
<script>
Vue.component('button-conters', {
data: function() {
return {
count: 0
}
},
template: '<button v-on:click="count += 1">增加 count {{ count }}</button>'
})
new Vue({
el: '#button-counts'
})
</script>

当创建完成组建之后,我们可以无限次的进行引用,而组件中通常会带有一个名字,就比如上述创建的组件名称就是<button-conters>并根据创建一个创建Vue根实例化将组件作为自定义元素进行使用

1
2
3
new Vue({
el: '#button-counts'
})


之后直接在HTML中直接引入刚刚创建的组件即可作为HTML元素进行使用如:

1
2
3
<div id="button-counts">
<button-conters></button-conters>
</div>

复用组件


当组件创建完成之后我们可以在上述的基础上进行多次复用且独立,如:

1
2
3
4
5
6
<div id="button-counts">
<button-conters></button-conters>
<button-conters></button-conters>
<button-conters></button-conters>
<button-conters></button-conters>
</div>

当点击按钮的时候,上述的flag将会被证实,就因为每个组件都会各自独立并维护他的count,每次使用<button-conters>都会有一个新的实例会被新建。

同步


当以往常一样通过data直接定义且不通过data 函数则可返回对象的独立访问,如:

1
2
3
4
5
6
7
8
9
10
11
12
var buttonRepeat =  {
count: 0
}
Vue.component('button-conters', {
data: function() {
return buttonRepeat
},
template: '<button v-on:click="count += 1">增加 count {{ count }}</button>'
})
new Vue({
el: '#button-counts'
})


由于每个count是共享的所以当点击一个组件的同时,所有复用的组件都会被增加,所以正确的方式是通过使用独立函数进行编写组件,来不影响组件之间的复用:

1
2
3
4
5
6
7
8
9
10
11
Vue.component('button-conters', {
data: function() {
return {
count: 0
}
},
template: '<button v-on:click="count += 1">增加 count {{ count }}</button>'
})
new Vue({
el: '#button-counts'
})

组件的组织


通常一个应用会一一棵嵌套的组建树形式来组织,在vue当中,组件的注册需要让vue能够进行识别,所以注册主键一共分为两种类型,分别为全局注册以及局部注册,vue中所有的组件都是通过Vue.component来进行注册。

而局部注册主要通过使用var ComponentOne {}来进行注册,全局注册主要通过使用Vue.component('组件名', {})来进行注册,这里两者的区别就是命名方式的不同

全局注册组件格式

1
2
3
Vue.component('组件名称' {
// ……
})

局部注册

1
2
3
var ComponentOne = {
// ……
}

Prop 向子组件传递数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

![](https://49812933408852955071488026628034-1301075051.cos.ap-nanjing.myqcloud.com/1615400560_20210310232123160_1093282140.png)
在官方文档中,Prop向子组件传递数据主要用于**向这个组件传递一个标题或者内容之类的展示数据**,Prop是你可以在组建上注册一些自定义的**属性**,当一个**值传递给一个 prop 属性**。

```vue
<div id="data-title">
<data-title title="Hello,world"></data-title>
<data-title title="Hello,Vue"></data-title>
</div>
<script>
Vue.component('data-title', {
props: ['title'],
template: '<h1>{{title}}</h1>'
})
new Vue({el: '#data-title'})
</script>


除此之外我们还可以使用动态赋予一个变量的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="data-title">
<data-title
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"></data-title>
</div>
<script>
new Vue({
el: '#data-title',
data: {
posts: [
{ id: 1, title: 'Hello,world!'},
{ id: 2, title: 'Hello,Vue!'},
{ id: 3, title: 'Hello,Laravel!'},
]
}
})
Vue.component('data-title', {
props: ['title'],
template: '<h4>{{title}}</h4>'
})
new Vue({el: '#data-title'})
</script>

监听子组件事件


在开发<text-post组件的时候,就会涉及到父级组件的协调来实现一个文字的放大效果以及默认字体大小。首先我们在父组件,即#text-posts-events中添加一个postFontSize数据属性来设置默认的字号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div id="text-posts-events">
<div :style="{ fontSize: postFontSize + 'em' }">
<text-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
v-on:enlarge-text="postFontSize += 0.1"
>
</text-post>
</div>
</div>
<script>
Vue.component('text-post', {
props: ['post'],
template: '\
<div class="text-post">\
<h3>{{post.title}}\
<button v-on:click="$emit(\'enlarge-text\')">\
字体放大\
</button>\
<div v-html="post.content"></div>\
</div>\
'
})
new Vue({
el: '#text-posts-events',
data: {
posts: [
{id:1, title: 'Hello,vue!', content:'vue'},
{id:2, title: 'Hello,Laravel!', content:'laravel'}
],
postFontSize: 1
}
})
</script>
⬅️ Go back